package net.keebook.webapp.bean;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import javax.inject.Inject;

import net.keebook.webapp.dao.AccountConfirmationDao;
import net.keebook.webapp.dao.SettingDao;
import net.keebook.webapp.dao.UserDao;
import net.keebook.webapp.entity.AccountConfirmation;
import net.keebook.webapp.entity.User;
import net.keebook.webapp.model.SessionModel;
import net.keebook.webapp.util.DateUtil;
import net.keebook.webapp.util.Mail;
import net.keebook.webapp.util.MessageBundle;
import net.keebook.webapp.util.Messages;
import net.keebook.webapp.util.SettingId;


@ManagedBean
@RequestScoped
public class UserSettingsBean {
	private String timezone;
	private String name;
	private String email;
	private Boolean groupItems;
	private SessionModel sessionModel;
	
	@Inject
	private UserDao userDao;
	
	@Inject
	private SettingDao settingDao;
	
	@Inject
	private AccountConfirmationDao accountConfirmationDao;
	
	@PostConstruct
	public void init() {
		setSessionModel(SessionModel.getInstance(FacesContext.getCurrentInstance()));
		
		User user = getUserDao().get(getSessionModel().getUserId());
		setTimezone(user.getTimezone());
		setName(user.getName());
		setEmail(user.getEmail());
		setGroupItems(user.getGroupItems());
	}
	
	public void apply() throws IOException {
		User user = getUserDao().get(getSessionModel().getUserId());
		
		boolean emailAddressChanged = false;
		if (!getEmail().equalsIgnoreCase(user.getEmail())) {
			emailAddressChanged = true;
			user.setConfirmed(false);
		}
		
		user.setTimezone(getTimezone());
		user.setName(getName());
		user.setEmail(getEmail());
		user.setGroupItems(getGroupItems());
		getUserDao().update(user);
		
		if (emailAddressChanged) {
			getAccountConfirmationDao().deleteAllUserConfirmations(user.getId());
			
			AccountConfirmation confirmation = new AccountConfirmation();
			confirmation.setUser(user);
			confirmation.setCreationDate(DateUtil.getUtcTimestamp(TimeZone.getTimeZone(getSettingDao().get(SettingId.SYSTEM_TIMEZONE).getValue())));
			getAccountConfirmationDao().store(confirmation);
			
			String url = getSettingDao().get(SettingId.PUBLIC_URL).getValue() + "/services/confirm/" + confirmation.getExposableId();
			String message = MessageBundle.get().getString("mail.changeAddressMail");
			message = MessageFormat.format(message, url);
			
			Mail mail = new Mail(
					getSettingDao().get(SettingId.SMTP_HOST).getValue(), 
					getSettingDao().get(SettingId.SMTP_PORT).getLong().intValue(),
					getSettingDao().get(SettingId.SMTP_AUTH).getBoolean(),
					getSettingDao().get(SettingId.SMTP_USERNAME).getValue(),
					getSettingDao().get(SettingId.SMTP_PASSWORD).getValue(),
					getSettingDao().get(SettingId.SMTP_ENABLE).getBoolean());
			try {
				mail.sendMail(
					getSettingDao().get(SettingId.SMTP_SENDER_ADDRESS).getValue(),
					"KeeBook",
					getEmail(),
					null,
					MessageBundle.get().getString("mail.changeAddressMailSubject"),
					message);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		FacesContext.getCurrentInstance().getExternalContext().redirect("settings.xhtml?msg="+Messages.SETTINGS_APPLIED);
	}
	
	public List<SelectItem> getTimezones() {
		List<SelectItem> result = new ArrayList<SelectItem>();
		String[] ids = TimeZone.getAvailableIDs();
		for (String id : ids) {
			TimeZone tz = TimeZone.getTimeZone(id);
			int rawOffset = tz.getRawOffset();
		    int hour = rawOffset / (60*60*1000);
		    int min = Math.abs(rawOffset / (60*1000)) % 60;
		    
		    String time = (hour >= 0 ? "+" : "-") + (Math.abs(hour)) + ":" + (min < 9 ? "0"+min : min);
			String s = "(UTC"+time+") "+ TimeZone.getTimeZone(id).getDisplayName(Locale.US) +" ("+id+")";
		    
			result.add(new SelectItem(id, s));
		}
		return result;
	}

	public UserDao getUserDao() {
		return userDao;
	}

	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	public String getTimezone() {
		return timezone;
	}

	public void setTimezone(String timezone) {
		this.timezone = timezone;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public SessionModel getSessionModel() {
		return sessionModel;
	}

	public void setSessionModel(SessionModel sessionModel) {
		this.sessionModel = sessionModel;
	}

	public SettingDao getSettingDao() {
		return settingDao;
	}

	public void setSettingDao(SettingDao settingDao) {
		this.settingDao = settingDao;
	}

	public AccountConfirmationDao getAccountConfirmationDao() {
		return accountConfirmationDao;
	}

	public void setAccountConfirmationDao(AccountConfirmationDao accountConfirmationDao) {
		this.accountConfirmationDao = accountConfirmationDao;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Boolean getGroupItems() {
		return groupItems;
	}

	public void setGroupItems(Boolean groupItems) {
		this.groupItems = groupItems;
	}
}
